import * as React from 'react';
import { Button, Text, TextInput, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import AsyncStorage from '@react-native-async-storage/async-storage';

// createContext 创建上下文
const AuthContext = React.createContext();

function HomeScreen() {
  // useContext 可以获取上下文中的数据（跨组件层级获取数据）
  const { signOut } = React.useContext(AuthContext);

  return (
    <View>
      <Text>已经登陆!</Text>
      <Button title="退出" onPress={signOut} />
    </View>
  );
}

function SignInScreen() {
  // useState 中接收唯一的参数，是状态的初始值
  // 返回值为数组，第一个元素是状态名，第二个是修改状态的方法，写法固定，以 set 开头
  const [username, setUsername] = React.useState('');
  const [password, setPassword] = React.useState('');

  const { signIn } = React.useContext(AuthContext);

  return (
    <View>
      <TextInput
        placeholder="用户名"
        value={username}
        onChangeText={setUsername}
      />
      <TextInput
        placeholder="密码"
        value={password}
        onChangeText={setPassword}
        secureTextEntry
      />
      <Button title="登陆" onPress={() => signIn({ username, password })} />
    </View>
  );
}

const Stack = createStackNavigator();

export default function App({ navigation }) {

  // useReducer（reducer，initState）
  const [state, dispatch] = React.useReducer(
    (prevState, action) => {
      switch (action.type) {
        case 'RESTORE_TOKEN':
          return {
            ...prevState,
            userToken: action.token,
          };
        case 'SIGN_IN':
          return {
            ...prevState,
            isSignout: false,
            userToken: action.token,
          };
        case 'SIGN_OUT':
          return {
            ...prevState,
            isSignout: true,
            userToken: null,
          };
      }
    },
    {
      isSignout: false,
      userToken: null,
    }
  );

  // useEffect 相当于类组件的生命周期
  React.useEffect(() => {
    // 获取存储中的 token ，然后导航到响应的位置
    const bootstrapAsync = async () => {
      let userToken;

      try {
        userToken = await AsyncStorage.getItem('userToken');
      } catch (e) {
        // Restoring token failed
      }

      // 取到数据后，更新到状态中
      dispatch({ type: 'RESTORE_TOKEN', token: userToken });
    };

    bootstrapAsync();
  }, []);

  // useMemo 相当于 Vue 中的计算属性（computed），用来检测数据变化
  const authContext = React.useMemo(
    () => ({
      signIn: async data => {
        // 执行登陆。可能与后端接口对接，也可以将登陆数据持久化存储到 AsyncStorage 中
        dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
      },
      signOut: () => dispatch({ type: 'SIGN_OUT' }),
      signUp: async data => {
        // 执行登陆。可能与后端接口对接，也可以将登陆数据持久化存储到 AsyncStorage 中
        dispatch({ type: 'SIGN_IN', token: 'dummy-auth-token' });
      },
    }),
    []
  );

  return (
    <AuthContext.Provider value={authContext}>
      <NavigationContainer>
        <Stack.Navigator>
          {state.userToken == null ? (
            // 本地没有 token ，说明用户未登陆
            <Stack.Screen name="SignIn" component={SignInScreen} options={{title:'登陆'}} />
          ) : (
            // 用户已经登陆
            <Stack.Screen name="Home" component={HomeScreen} />
          )}
        </Stack.Navigator>
      </NavigationContainer>
    </AuthContext.Provider>
  );
}